const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');
const dotenv = require('dotenv');

// Load environment variables
dotenv.config({ path: path.join(__dirname, '..', 'backend', '.env') });

// Backup directory
const BACKUP_DIR = path.join(__dirname, '..', 'backups');

// Ensure backup directory exists
if (!fs.existsSync(BACKUP_DIR)) {
  fs.mkdirSync(BACKUP_DIR, { recursive: true });
}

/**
 * Create a database backup
 */
function createBackup() {
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
  const backupFileName = `financeapp_backup_${timestamp}.sql`;
  const backupPath = path.join(BACKUP_DIR, backupFileName);
  
  // PostgreSQL connection details from environment variables
  const host = process.env.DB_HOST || 'localhost';
  const port = process.env.DB_PORT || '5432';
  const database = process.env.DB_NAME || 'financeapp';
  const username = process.env.DB_USER || 'financeapp_admin';
  
  // Create backup command
  const backupCommand = `pg_dump -h ${host} -p ${port} -U ${username} -d ${database} -f "${backupPath}"`;
  
  console.log(`Creating backup: ${backupFileName}`);
  
  // Set environment variable for password
  const env = { ...process.env, PGPASSWORD: process.env.DB_PASSWORD };
  
  exec(backupCommand, { env }, (error, stdout, stderr) => {
    if (error) {
      console.error(`Backup failed: ${error.message}`);
      return;
    }
    
    if (stderr) {
      console.error(`Backup stderr: ${stderr}`);
      return;
    }
    
    console.log(`Backup created successfully: ${backupPath}`);
  });
}

/**
 * Restore a database backup
 * @param {string} backupFile - The backup file to restore
 */
function restoreBackup(backupFile) {
  const backupPath = path.join(BACKUP_DIR, backupFile);
  
  // Check if backup file exists
  if (!fs.existsSync(backupPath)) {
    console.error(`Backup file not found: ${backupPath}`);
    return;
  }
  
  // PostgreSQL connection details from environment variables
  const host = process.env.DB_HOST || 'localhost';
  const port = process.env.DB_PORT || '5432';
  const database = process.env.DB_NAME || 'financeapp';
  const username = process.env.DB_USER || 'financeapp_admin';
  
  // Drop and recreate database command (be careful with this in production!)
  const dropCommand = `dropdb -h ${host} -p ${port} -U ${username} ${database}`;
  const createCommand = `createdb -h ${host} -p ${port} -U ${username} ${database}`;
  
  // Restore command
  const restoreCommand = `psql -h ${host} -p ${port} -U ${username} -d ${database} -f "${backupPath}"`;
  
  console.log(`Restoring backup: ${backupFile}`);
  
  // Set environment variable for password
  const env = { ...process.env, PGPASSWORD: process.env.DB_PASSWORD };
  
  // First drop the database
  exec(dropCommand, { env }, (error, stdout, stderr) => {
    if (error) {
      console.error(`Drop database failed: ${error.message}`);
      return;
    }
    
    // Then create the database
    exec(createCommand, { env }, (error, stdout, stderr) => {
      if (error) {
        console.error(`Create database failed: ${error.message}`);
        return;
      }
      
      // Finally restore the backup
      exec(restoreCommand, { env }, (error, stdout, stderr) => {
        if (error) {
          console.error(`Restore failed: ${error.message}`);
          return;
        }
        
        if (stderr) {
          console.error(`Restore stderr: ${stderr}`);
          return;
        }
        
        console.log(`Backup restored successfully from: ${backupPath}`);
      });
    });
  });
}

/**
 * List available backups
 */
function listBackups() {
  if (!fs.existsSync(BACKUP_DIR)) {
    console.log('No backups found');
    return;
  }
  
  const backups = fs.readdirSync(BACKUP_DIR)
    .filter(file => file.endsWith('.sql'))
    .sort((a, b) => b.localeCompare(a)); // Sort by name (newest first)
  
  if (backups.length === 0) {
    console.log('No backups found');
    return;
  }
  
  console.log('Available backups:');
  backups.forEach(backup => {
    console.log(`  ${backup}`);
  });
}

// Handle command line arguments
const args = process.argv.slice(2);

if (args.length === 0) {
  console.log('Usage:');
  console.log('  node backup.js create          - Create a new backup');
  console.log('  node backup.js restore <file>  - Restore from a backup file');
  console.log('  node backup.js list            - List available backups');
  process.exit(1);
}

const command = args[0];

switch (command) {
  case 'create':
    createBackup();
    break;
  case 'restore':
    if (args.length < 2) {
      console.error('Please specify a backup file to restore');
      process.exit(1);
    }
    restoreBackup(args[1]);
    break;
  case 'list':
    listBackups();
    break;
  default:
    console.error(`Unknown command: ${command}`);
    process.exit(1);
}